export default class RedPacketRain{
	
	// 定义需要用到的一些私有属性
	#canvasCtx;
	#imgBg;
	#drawImgPurse;
	#drawImgRedPacket;
	#isContinue=false;
	
	constructor(conf,window){
		// 这里做一些初始化的工作...
		// const { document } = context;
		if(conf.id==undefined) throw new Error('not find element id');
		Object.assign(conf,{
			redPackW:50,//红包的宽度
			//...
		});
		let box = document.getElementById(conf.id);
		let canvas = document.createElement('canvas');
		canvas.width = box.offsetWidth;
		canvas.height = Math.max(box.offsetHeight,canvas.width);
		const ctx = canvas.getContext('2d');
		ctx.textAlign = 'center';
		ctx.font = ctx.font.replace(/\d+/,23);
		//红包数据
		const redPack = {
			w: conf.redPackW,
			h: conf.redPackW*1.4,
			absX: 10,
			absY: 10
		};
		//钱袋子数据
		const purse = {
			w: conf.redPackW*2,
			h: conf.redPackW*2,
			x: 0,
			y: 0,
			absX: 100,
			absY: 10,
			count: 0,
			money: 0
		};
		//清空画布方法
		const drawClearEmpty = ()=>{
			ctx.clearRect(0,0,canvas.width,canvas.height);
		};
		//绘制红包方法
		const drawRedPacket = (x,y)=>{
			//绘制红包形状
			let r = redPack.w*0.1;
			ctx.fillStyle='#f00';
			ctx.strokeStyle='#333';
			ctx.beginPath();
			ctx.arc(x+r,y+r,r,Math.PI,-0.5*Math.PI);
			let x2 = x+redPack.w;
			ctx.lineTo(x2-r,y);
			ctx.arc(x2-r,y+r,r,-0.5*Math.PI,0);
			let y2 = y+redPack.h;
			ctx.lineTo(x2,y2-r);
			ctx.arc(x2-r,y2-r,r,0,0.5*Math.PI);
			ctx.lineTo(x+r,y2);
			ctx.arc(x+r,y2-r,r,0.5*Math.PI,Math.PI);
			ctx.closePath();
			ctx.fill();
			//绘制盖子
			let centerX = x+redPack.w/2;
			let centerY = y-redPack.w*0.6;
			ctx.save();
			ctx.clip();
			ctx.arc(centerX,centerY,redPack.w,-0.5*Math.PI,1.5*Math.PI);
			ctx.stroke();
			ctx.restore();
			//绘制盖子纽扣
			centerY = y+redPack.w*0.4;
			ctx.fillStyle='#991';
			ctx.beginPath();
			ctx.arc(centerX,centerY,redPack.w*0.15,0,2*Math.PI);
			ctx.fill();
			ctx.stroke();
			//绘制纽扣中间
			r = redPack.w*0.05;
			ctx.fillStyle='#000';
			ctx.beginPath();
			ctx.rect(centerX-r,centerY-r,2*r,2*r);
			ctx.fill();
		};
		//绘制钱袋子方法
		const drawPurse = (x,y)=>{
			let r = purse.w/2;
			let centerX = x + r;
			let centerY = y + purse.h-conf.redPackW*0.8;
			//绘制袋子容器形状
			ctx.fillStyle='#f55';
			ctx.beginPath();
			ctx.arc(centerX,centerY,r,0,2*Math.PI);
			ctx.fill();
			ctx.stroke();
			//绘制袋口
			ctx.beginPath();
			ctx.save();
			ctx.translate(-centerX*0.6,0);
			ctx.scale(1.6,1);
			ctx.arc(centerX,centerY-r*0.62,r*0.6,0,2*Math.PI);
			ctx.fill();
			ctx.stroke();
			ctx.beginPath();
			ctx.fillStyle='#333';
			ctx.arc(centerX,centerY-r*0.62,r*0.5,0,2*Math.PI);
			ctx.fill();
			ctx.stroke();
			ctx.restore();
			purse.h = purse.h+conf.redPackW*0.2;
		};
		//绘制袋子图片方法
		this.#drawImgPurse = (isSaved)=>{
			if(!isSaved) drawClearEmpty();
			ctx.drawImage(this.#imgBg,purse.absX,purse.absY,purse.w,purse.h,purse.x,purse.y,purse.w,purse.h);
			ctx.fillStyle='#ff5';
			let r = purse.w/2;
			ctx.fillText('￥'+purse.money.toFixed(2),purse.x+r,purse.y+(purse.h+r)*0.55,purse.w);
		};
		//绘制红包图片方法
		this.#drawImgRedPacket = (x,y)=>{
			ctx.drawImage(this.#imgBg,redPack.absX,redPack.absY,redPack.w,redPack.h,x,y,redPack.w,redPack.h);
		};
		
		//其它逻辑省略...
		
		//重绘方法
		const redraw = () => {
			//...
		};
		
		//封装上下文，开始和结束方法通过初始化完成后返回给外部调用
		const Context = {
			onStart:()=>{
				if(this.#isContinue) return;
				this.#isContinue=true;
				redraw();//开始时，调用重绘方法
			},
			onStop:(conf={})=>{
				if(!this.#isContinue) return;
				this.#isContinue=false;
				//停止后，将钱袋子的数据传给外部调用者
				if(typeof conf.success=='function') conf.success({
					count: purse.count,
					money: purse.money
				})
			}
		};
		//加载图片...
		(new Promise((resolve,reject)=>{
			drawRedPacket(redPack.absX,redPack.absY);
			drawPurse(purse.absX,purse.absY);
			let img = new Image();
			img.onload = ()=>resolve(img);
			img.onerror = reject;
			img.src = canvas.toDataURL();
		})).then(res=>{
			this.#imgBg=res;//绘制好后生成图片
			purse.x=(canvas.width-purse.w)/2;
			purse.y=canvas.height-purse.h;
			//接下来我们会以这个图片作为素材来绘制动画
			this.#drawImgPurse();
			if(typeof conf.success=='function') conf.success(Context);//传给外部
		}).catch(err=>{
			throw new Error(err)
		});
		this.#canvasCtx = ctx;
		box.appendChild(canvas);	
	}
}
